Skip to content

feat: add ESM static component assets#360

Merged
mohamedmansour merged 6 commits into
mainfrom
mmansour/component-assets
Jun 23, 2026
Merged

feat: add ESM static component assets#360
mohamedmansour merged 6 commits into
mainfrom
mmansour/component-assets

Conversation

@mohamedmansour

@mohamedmansour mohamedmansour commented Jun 19, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds ESM static component assets so WebUI apps can keep the initial SSR payload small while loading deferred component trees asynchronously from a CDN or static folder without @microsoft/webui-router and without a template server.

webui build --emit-component-assets <tags> compiles requested lazy roots through synthetic non-entry fragments, keeping them out of the initial SSR entry graph while still emitting their full component dependency closure as static .webui.js modules.

What changed

  • Emit one browser-native ESM asset per requested root, for example lazy-panel.webui.js.
    • The module default-exports template metadata, CSS module import maps, dependency closure metadata, and compiled condition functions together.
    • Static assets intentionally omit inventory state because they cannot know the page's current loaded template bitset.
  • Add @microsoft/webui-framework/component-asset.js with defineComponentAssets().
    • Starts asset, component module, and optional data work together.
    • Skips importing when the root template is already registered.
    • Deduplicates in-flight imports and CSS module import maps.
    • Creates elements after asset/module work is ready and applies data later via setState() by default, with optional bounded data blocking.
  • Move static component asset rendering into the Rust core API.
    • BuildOptions::component_asset_roots requests asset roots.
    • BuildResult::component_asset_files returns rendered [filename, ESM content] files.
    • render_component_assets() exposes the renderer for Rust callers.
    • build_to_disk() writes component assets alongside protocol.bin and CSS files.
  • Expose the same build surface through Node/npm.
    • Node native builds accept componentAssetRoots.
    • build() returns flattened componentAssetFiles ([filename, content, ...]) in addition to cssFiles.
  • Add generic emitted asset filename templating.
    • Reuses [name], [hash], [ext] for Link-mode CSS files and static component assets.
    • [ext] resolves to css for CSS and webui.js for component assets.
    • Protocol, CSS, and component asset filenames are validated together before writes, preventing partial output and overwrite collisions.
  • Keep static .webui.js modules out of preload/link handling; only CSS assets use the existing CSS preload/link paths.
  • Remove synthetic asset-root wrapper fragments before protocol serialization so asset-only wrappers do not bloat protocol.bin.
  • Add examples/app/component-assets showing a no-router, no-template-server deferred component flow.
  • Update DESIGN.md, CLI docs, Rust/Node integration docs, AI docs, interactivity docs, package READMEs, and framework docs.

Follow-ups filed

Validation

  • cargo test -p microsoft-webui -p microsoft-webui-cli --lib
  • cargo test -p microsoft-webui-cli
  • cargo test -p microsoft-webui-node --lib
  • cd packages/webui && pnpm build && pnpm test
  • cargo xtask fmt
  • cargo xtask clippy

@mohamedmansour mohamedmansour force-pushed the mmansour/component-assets branch 2 times, most recently from 0520ee8 to 52549a3 Compare June 19, 2026 23:37
@mohamedmansour mohamedmansour requested review from a team, akroshg, janechu and mcritzjam June 20, 2026 05:40
@mohamedmansour mohamedmansour changed the title feat: add static component assets feat: add ESM static component assets Jun 22, 2026
@mohamedmansour mohamedmansour requested a review from Qusic June 23, 2026 02:32
mohamedmansour and others added 4 commits June 22, 2026 20:28
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add Playwright coverage for lazy component asset loading and cache reuse, wire the example into xtask e2e and demo packaging, and document the create-example workflow.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@mohamedmansour mohamedmansour force-pushed the mmansour/component-assets branch from 0093cc1 to 2dbaf0f Compare June 23, 2026 03:31
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Qusic
Qusic previously approved these changes Jun 23, 2026
Comment thread crates/webui/src/component_assets.rs
Comment thread crates/webui/src/component_assets.rs
Comment thread crates/webui/src/lib.rs
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@mohamedmansour mohamedmansour merged commit 1864ffa into main Jun 23, 2026
21 checks passed
@mohamedmansour mohamedmansour deleted the mmansour/component-assets branch June 23, 2026 23:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants